<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

</body>
<script>
    // ----------------复习一下js  this----------------------
    //  解析器在调用函数每次都会向函数内部传递一个隐含的参数，
    //      这个隐含的参数就是this，this指向的是一个对象
    //      这个对象我们称为函数执行的上下文对象
    //      根据函数的调用方式不同，this会指向不同的对象
    //      1：以函数的形式直接调用的时候，this永远指向的是window   fun（）；或者说一个function如果没有调用者，其调用者默认就是window
    //      2：以对象.方法的形式调用时候，this就是调用该方法的对象
    //      3：以构造函数的形式来调用【new fun（）】 this，指向实例对象；普通函数，this指向window。构造函数其实就是new之后的普通函数
    // ====
    //      this和箭头函数的值可以一言以蔽之：
    //      箭头函数：this等同于上一层非箭头的函数的this值或全局对象（window或undefined）
    //      普通函数this：谁调用归谁
    //      无论对象嵌套有多深,因为作为对象的方法箭头函数不是被普通函数包含,那么this总是指向window对象
    function fun() {
        console.log(`${this.name}====fun`)
    }

    var name = "唐僧"
    var obj = {
        name: "孙悟空",
        say: fun,
        hello: () => {
            // 对象不能形成一个作用域,所以当前箭头函数的this指向的是window
            //      无论对象嵌套有多深,因为作为对象的方法箭头函数不是被普通函数包含,那么this总是指向window对象
            console.log(`${this.name}====obj.hello`)
        },
        sub1: {
            name: "sub1",
            say() {
                console.log(`${this.name}====obj.sub1.say`)
            },
            hello: () => {
                //      无论对象嵌套有多深,因为作为对象的方法箭头函数不是被普通函数包含,那么this总是指向window对象
                console.log(`${this.name}====obj.sub1.hello`)
            }
        }
    }
    fun();// 唐僧  = window.fun()
    obj.say();// 孙悟空
    obj.hello();// 唐僧
    obj.sub1.say()// sub1
    obj.sub1.hello()// 唐僧

    function Person(name) {
        this.name = name
        this.sayHi = function () {
            console.log(this)
        }
    }

    var p = new Person("张三")
    p.sayHi();//输出p这个对象，且这个对象的name是【张三】

    //call 方法  call(x)  call方法也可以修改this的指向，第一个实例对象是是谁，this指向的就是谁
    fun.call(p);//【张三】 ,P对象的name
</script>
</html>
